#include "BspCan.h"
CanRxMsg Rx0Message;
CanRxMsg Rx1Message;
void(*CanRx0_Handle)(uint16_t ID,uint8_t *Dat,uint8_t Len); 
void(*CanRx1_Handle)(uint16_t ID,uint8_t *Dat,uint8_t Len);
uint8_t MailBoxFlag[3] = {0,0,0};
/*********************************************************************************************
  * @brief  BspCan1IoConfig
  * @param  None
  * @retval None 
	* @IO CAN1_RX ---------------------- PA11
  * @IO CAN1_TX ---------------------- PA12
  ********************************************************************************************/
static void BspCan1IoConfig(void)
{
	GPIO_InitTypeDef  GPIOX;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
	
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_CAN1);
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_CAN1);
	
	GPIOX.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
	GPIOX.GPIO_OType = GPIO_OType_PP;
	GPIOX.GPIO_PuPd = GPIO_PuPd_UP;
	GPIOX.GPIO_Mode = GPIO_Mode_AF;
	GPIOX.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_Init(GPIOA,&GPIOX);
}

/*********************************************************************************************
  * @brief  BspCan1Config
  * @param  None
  * @retval None 
	* @IO None
  ********************************************************************************************/
static void BspCan1Config(void)
{
	NVIC_InitTypeDef  NVICX;
	CAN_InitTypeDef  CANX;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);
	
//	NVICX.NVIC_IRQChannel = CAN1_TX_IRQn;
//	NVICX.NVIC_IRQChannelPreemptionPriority = 7;
//	NVICX.NVIC_IRQChannelSubPriority = 0;
//	NVICX.NVIC_IRQChannelCmd = ENABLE;
//	NVIC_Init(&NVICX);
	
	NVICX.NVIC_IRQChannel = CAN1_RX0_IRQn;
	NVICX.NVIC_IRQChannelPreemptionPriority = 6;
	NVICX.NVIC_IRQChannelSubPriority = 0;
	NVICX.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVICX);
	
	NVICX.NVIC_IRQChannel = CAN1_RX1_IRQn;
	NVICX.NVIC_IRQChannelPreemptionPriority = 5;
	NVICX.NVIC_IRQChannelSubPriority = 0;
	NVICX.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVICX);
	
	CAN_DeInit(CAN1);
	CANX.CAN_TTCM = DISABLE;  //使能或者失能时间出发模式
	CANX.CAN_ABOM = DISABLE;  //使能或者失能制动离线模式
	CANX.CAN_AWUM = DISABLE;  //使能或者失能自动唤醒模式
	CANX.CAN_NART = ENABLE;  //使能或者失能非自动重传输模式
	CANX.CAN_RFLM = DISABLE;  //使能或者失能接收FIFO锁定模式
	CANX.CAN_TXFP = ENABLE;  //使能货值使能发送FIFO优先级
	CANX.CAN_Mode = CAN_Mode_Normal;  //CAN模式选择
	
  /********************************************************* 
	*波特率 = F/((SJW+BS1+BS2)*PRE) 
	*采样点（75%） = ( 1 +  CAN_BS1) /  (1 +  CAN_BS1 +  CAN_BS2)
	*********************************************************/
//	CANX.CAN_Prescaler = 7;  //设定一个时间段的长度
//	CANX.CAN_SJW = CAN_SJW_1tq;  //设定了重新同步跳跃宽度
//	CANX.CAN_BS1 = CAN_BS1_8tq;  //设定了第一个时间段的宽度
//	CANX.CAN_BS2 = CAN_BS2_3tq;  //设定了第二个时间段的宽度
//	CAN_Init(CAN1,&CANX);
	
	CANX.CAN_Prescaler = 12;  //设定一个时间段的长度//250k
	CANX.CAN_SJW = CAN_SJW_1tq;  //设定了重新同步跳跃宽度
	CANX.CAN_BS1 = CAN_BS1_9tq;  //设定了第一个时间段的宽度
	CANX.CAN_BS2 = CAN_BS2_4tq;  //设定了第二个时间段的宽度
	CAN_Init(CAN1,&CANX);
}

/*********************************************************************************************
  * @brief  BspCan1FilterConfig
  * @param  None
  * @retval None 
	* @IO None
  ********************************************************************************************/
static void BspCan1FilterConfig(uint8_t Node_ID)
{
	CAN_FilterInitTypeDef  CAN_FX;
	uint16_t Filter_ID = 0;
	Filter_ID = Node_ID;
//	CAN_FX.CAN_FilterNumber = 0;  //设置过滤器编号
//	CAN_FX.CAN_FilterMode = CAN_FilterMode_IdMask;  //设置过滤器工作模式
//	CAN_FX.CAN_FilterScale = CAN_FilterScale_16bit;  //设置过滤器位宽
//	CAN_FX.CAN_FilterIdLow = (Filter_ID << 5) & 0XFFE0;  //过滤器底字节（16Bit）
//	CAN_FX.CAN_FilterIdHigh = (0X3FF << 3) & 0XFFF8;  //过滤器高字节（16Bit）
//	CAN_FX.CAN_FilterMaskIdLow = (Filter_ID << 5) & 0XFFE0;
//	CAN_FX.CAN_FilterMaskIdHigh = (0X3FF << 3) & 0XFFF8;
//	CAN_FX.CAN_FilterFIFOAssignment = CAN_FilterFIFO1; //过滤器关联到FIFO0
//	CAN_FX.CAN_FilterActivation = ENABLE; //激活过滤器
//	CAN_FilterInit(&CAN_FX);
	
	CAN_FX.CAN_FilterNumber = 0;  //设置过滤器编号
	CAN_FX.CAN_FilterMode = CAN_FilterMode_IdList;  //设置过滤器工作模式
	CAN_FX.CAN_FilterScale = CAN_FilterScale_16bit;  //设置过滤器位宽
	CAN_FX.CAN_FilterIdLow = (Filter_ID << 5) | (0X0600 << 5);  //过滤器底字节（16Bit）
	CAN_FX.CAN_FilterIdHigh = (0X0080 << 5);  //过滤器高字节（16Bit）
	CAN_FX.CAN_FilterMaskIdLow = 0X0000;
	CAN_FX.CAN_FilterMaskIdHigh = 0X0000;
	CAN_FX.CAN_FilterFIFOAssignment = CAN_FilterFIFO0; //过滤器关联到FIFO0
	CAN_FX.CAN_FilterActivation = ENABLE; //激活过滤器
	CAN_FilterInit(&CAN_FX);
}

/*********************************************************************************************
  * @brief  BspCan1_Init
  * @param  TypeDefBspCanStruct *CAN_p CAN 初始化参数结构体指针
  * @retval uint8_t  0 初始化成功   1 初始化参数错误 
	* @IO None
  ********************************************************************************************/
uint8_t BspCan1_Init(TypeDefBspCanStruct *CAN_p)
{
	MailBoxFlag[0] = 0;
	MailBoxFlag[1] = 0;
	MailBoxFlag[2] = 0;
	CanRx0_Handle = 0;
	CanRx1_Handle = 0;
	CanRx0_Handle = CAN_p->CanRx0_Handle;
	CanRx1_Handle = CAN_p->CanRx1_Handle;
	if((CanRx0_Handle != 0) && (CanRx1_Handle != 0) && (CAN_p->NodeID != 0))
	{
		BspCan1IoConfig();
		BspCan1Config();
		BspCan1FilterConfig(CAN_p->NodeID);
//		CAN_ITConfig(CAN1,CAN_IT_TME,ENABLE);  // 使能发送中断
		CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);  // 使能 FIFO0 接收中断
		CAN_ITConfig(CAN1,CAN_IT_FMP1,ENABLE);  // 使能 FIFO1 接收中断
		return 0;
	}
	return 1;
}

/*********************************************************************************************
  * @brief  CAN1_RX0_IRQHandler CAN1 RX0接收数据中断
  * @param  None
  * @retval None 
	* @IO None
  ********************************************************************************************/
void CAN1_RX0_IRQHandler(void)
{
	if(CAN_GetITStatus(CAN1,CAN_IT_FMP0) == SET)
	{
		CAN_Receive(CAN1,CAN_FIFO0,&Rx0Message);
		CanRx0_Handle(Rx0Message.StdId,Rx0Message.Data,Rx0Message.DLC);
	}
}

/*********************************************************************************************
  * @brief  CAN1_RX1_IRQHandler CAN1 RX1接收数据中断
  * @param  None
  * @retval None 
	* @IO None
  ********************************************************************************************/
void CAN1_RX1_IRQHandler(void)
{
	if(CAN_GetITStatus(CAN1,CAN_IT_FMP1) == SET)
	{
		CAN_Receive(CAN1,CAN_FIFO1,&Rx1Message);
		CanRx1_Handle(Rx1Message.StdId,Rx1Message.Data,Rx1Message.DLC);
	}
}

/*********************************************************************************************
  * @brief  Can1SendData
  * @param  uint16_t StdId 帧 ID
  * @param  uint8_t *Buff 需要发送的数据指针
  * @param  uint8_t Len 需要发送的数据长度，不能超过8个字节
  * @retval uint8_t  0 ~ 2 有效邮箱    4 没有发送邮箱     5 长度超过8个字节 
	* @IO None
  ********************************************************************************************/
uint8_t Can1SendData(uint16_t StdId,uint8_t *Buff,uint8_t Len)
{
	CanTxMsg TxMsg;
	uint8_t Index;
	uint8_t MsgBox = 0;
	if(Len > 8)
	return 0x05;
	TxMsg.StdId = StdId;
	TxMsg.DLC = Len;
	TxMsg.IDE = CAN_Id_Standard;
	TxMsg.RTR = CAN_RTR_Data;
	TxMsg.ExtId = 0;
	for(Index = 0;Index < Len;Index++)
	{
		TxMsg.Data[Index] = Buff[Index];
	} 
//	 while((CAN_GetFlagStatus(CAN1, CAN_FLAG_RQCP0) !=RESET) || \
//				 (CAN_GetFlagStatus(CAN1, CAN_FLAG_RQCP1) !=RESET) || \
//				 (CAN_GetFlagStatus(CAN1, CAN_FLAG_RQCP2) !=RESET));
CAN1_REPETA_TX: 
		MsgBox = CAN_Transmit(CAN1, &TxMsg);
	  if(MsgBox == CAN_TxStatus_NoMailBox)
			 goto CAN1_REPETA_TX;
	return MsgBox;
}

